﻿using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NDBGen.Configuration;
using NDBGen.DataAccess;
using NDBGen.Plugins.DataAccess;
using NDBGen.Tests;

namespace NDBGen.Plugins.Tests
{
    [TestClass]
    public class LinqToSqlDataAccessCodeGeneratorTests : UnitTestBase<DataAccessGeneratorPluginData>
    {
        [TestInitialize]
        public override void TestInitialize()
        {
            base.TestInitialize();
        }

        protected override DataAccessGeneratorPluginData GetPluginData(ParsedInput parsedInput)
        {
            return parsedInput.CreateDataAccessPluginData();
        }

        [TestMethod]
        public void TestComposition()
        {
            var catalog = new AssemblyCatalog(typeof(LinqToSqlDataAccessCodeGenerator).Assembly);
            using (var container = new CompositionContainer(catalog))
            {
                var tester = new CompositionTester<IColumnDataTypeCodeSnippetGenerator, IGeneratorMetadata>();
                container.ComposeParts(tester);

                Assert.IsNotNull(tester.Imports);
                Assert.IsTrue(tester.Imports.Any());
            }
        }

        private String Generate(ParsedInput parsedInput)
        {
            var pluginData = parsedInput.CreateDataAccessPluginData();
            var generator = new LinqToSqlDataAccessCodeGenerator();
            generator.Init(pluginData);

            var b = new StringBuilderStream();
            var config = new SchemaDataAccessOutputElement();
            config.Settings.Add(new SettingElement { Name = "rootNamespace", Value = "MyApplication.Models.Domain" });
            using (var writer = new IndentedTextWriter(b))
            {
                foreach (var table in parsedInput.Tables)
                {
                    generator.WriteModel(config, table, writer);
                }
            }

            return b.ToString().Trim();
        }

        [TestMethod]
        public void GenerateSingleProperty()
        {
            var tableInput = DotNetTestResources.GenerateSingleProperty_Input;
            var parsedInput = ParsedInputUtil.CreateParsedInput(tableInput);

            var expected = DotNetTestResources.GenerateSingleProperty_Output;
            var actual = Generate(parsedInput);

            CompareLines(expected, actual);
        }

        [TestMethod]
        public void GenerateCSharp_Test1()
        {
            var tableInput = DotNetTestResources.GenerateCSharp_Test1_Input;
            var seedInput = DotNetTestResources.GenerateCSharp_Test1_InputSeedData;
            var parsedInput = ParsedInputUtil.CreateParsedInput(tableInput, @"Resources\GenerateCSharp_Test1_InputSeedData.txt", seedInput);

            var expected = DotNetTestResources.GenerateCSharp_Test1_Output.Trim();
            var actual = Generate(parsedInput);

            CompareLines(expected, actual);
        }

        [TestMethod]
        public void GenerateCSharp_Test2()
        {
            var tableInput = DotNetTestResources.GenerateCSharp_Test2_Input;
            var parsedInput = ParsedInputUtil.CreateParsedInput(tableInput);

            var expected = DotNetTestResources.GenerateCSharp_Test2_Output.Trim();
            var actual = Generate(parsedInput);

            CompareLines(expected, actual);
        }

        [TestMethod]
        public void GenerateMockApi_CSharpTest()
        {
            var tableInput = DotNetTestResources.MockApi_Input_Tables;
            var seedInput = DotNetTestResources.MockApi_Input_ScriptedData;
            var parsedInput = ParsedInputUtil.CreateParsedInput(tableInput, @"Resources\GenerateCSharp_Test1_InputSeedData.txt", seedInput);

            var expected = DotNetTestResources.MockApi_CSharp_Output.Trim();
            var actual = Generate(parsedInput);

            CompareLines(expected, actual);
        }

    }
}